#include <Arduino.h>
#include <WiFi.h>       //用于基础WiFi连接
#include <AsyncTCP.h>   //ESPAsyncWebServer.h的前置组件 这个库需要下载组件安装 https://github.com/me-no-dev/ESPAsyncWebServer
#include <ESPAsyncWebServer.h>  //用于websever和webstocket的建立 
#include "string.h"         //用于对字符串进行处理
#include <stdlib.h>        //用于整型转字符型
#include <cJson.h>         //用于解析json和构造json数据
#include "DHT.h"           //温湿度传感器驱动
#include "Adafruit_NeoPixel.h"   //用于控制灯带https://github.com/adafruit/Adafruit_NeoPixel 

#include <Adafruit_GFX.h>    // Core graphics library by Adafruit
#include <Arduino_ST7789.h> // Hardware-specific library for ST7789 (with or without CS pin)
#include <SPI.h>

DHT DHT11; //实例化一个温湿度对象

#define key_pin   0

#define TFT_DC    13
#define TFT_RST   15 
#define TFT_CS    12 // only for displays with CS pin
#define TFT_MOSI  2   // for hardware SPI data pin (all of available pins)
#define TFT_SCLK  14   // for hardware SPI sclk pin (all of available pins)
Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS);

#define T_S_pin    26 
#define led_pin    4            
#define ligth_pin  34

#define ws2812_pin 16   
#define NUMPIXELS 16
Adafruit_NeoPixel pixels(NUMPIXELS, ws2812_pin, NEO_GRB + NEO_KHZ800);//实例化对象


#define led_on  digitalWrite(led_pin,HIGH)
#define led_off  digitalWrite(led_pin,LOW)

typedef struct {             //定义一个用户变量
  const char* u_nume ;
  const char* u_pawd ; 
}user;
user hujingxuan={     //用户实例化
.u_nume="221300",
.u_pawd="888888"
};

typedef struct {//用于存储数据的结构体
  char ledstate[20];
  uint8_t LedState_value;
  uint8_t RGB_R;
  uint8_t RGB_G;
  uint8_t RGB_B;
  char ControlState[20];
  uint8_t engine;

}ControlData;
ControlData mdata={    //用于存储数据的结构体实例化,默认值
  "led_off",
  0,                  //亮度
  0,                  //R
  150,                //G
  0,                  //B
  "Manual",
  0
};


AsyncWebServer server(80);    //web端口号 80
const char* PARAM_MESSAGE = "usernum";  
char connet_flag=0;//是否建立stocketl连接标志

int Humidity,Temperature; //温湿度
static char *json_data; //json数据对象

const char* ssid = "DESKTOP";        //wifi密码和名称
const char* password = "11111111";



const char* web_main="<HTML>"   //登录页面
			"<HEAD>"
			"    <META charset=\"utf-8\">"
			"    <META NAME=\"GENERATOR\" Content=\"Microsoft Visual Studio\">"
			"    <TITLE>测试网页</TITLE>"
			"</HEAD>"
			"<BODY>"
			"    <p style=\"color:red \"> <font size=\"5\">大棚温室光照登录系统</font>  </p>"
			"    <form action=\"/post\" method=\"post\">"
			"        <p> 账号: <input type=\"number\" name=\"usernum\" placeholder=\"请输入账号\" required=\"required\"/></p>"
			"        <p> 密码: <input type=\"password\" name=\"pswd\" placeholder=\"请输入密码\" required=\"required\"/></p>"
			"        <p><input type=\"submit\"/>      <input type=\"reset\"/>       </p>"
			"    </form>"
			"</BODY>"
			"</HTML>";
String web_app = String("") +         //控制页面          
      "<!DOCTYPE html>\n"+
      "<html>\n"+
      "<head>\n"+
      "    <meta charset=\"UTF-8\">\n"+
      "    <title>WebSocket Test</title>\n"+
      "    <script>\n"+
      "        var txtJson ={          //要发送的json数据\n"+
      "            \"ledstate\": \"led_off\",\n"+
      "            \"LedState_value\": \"0\",\n"+
      "            \"ControlState\": \"Manual\",\n"+
      "            \"RGB_R\": \"0\",\n"+
      "            \"RGB_G\": \"150\",\n"+
      "            \"RGB_B\": \"0\",\n"+
      "            \"engine\": \"0\"\n"+
      "        }\n"+
      "        var ws;\n"+
      "        window.onload = function () {\n"+
      "            if (\"WebSocket\" in window) {\n"+
      "                ws = new WebSocket(\"ws://\" + window.location.host + \"/\"); // 建立WebSocket连接\n"+
      "                ws.onopen = function () { // 连接建立成功时触发\n"+
      "                    document.getElementById(\"info\").innerHTML += \"WebSocket连接成功!\" + \"<br>\";\n"+
      "                    ws.send(\"connect ok!\"); // 向服务器发送数据\n"+
      "                };\n"+
      "                ws.onmessage = function (evt) { // 收到服务器数据时触发\n"+
      "                    var obj = JSON.parse(evt.data);\n"+
      "                    document.getElementById(\"TemperatureIntensity\").innerHTML = obj.Temperature;\n"+
      "                    document.getElementById(\"HumidityIntensity\").innerHTML = obj.Humidity;\n"+
      "                    document.getElementById(\"LightIntensity\").innerHTML = obj.light;\n"+
      "                    document.getElementById(\"ControlState\").innerHTML = obj.ControlState;\n"+
      "                    document.getElementById(\"LedState\").innerHTML = obj.ledstate;\n"+
      "                    document.getElementById(\"idRGB_Rvalue\").innerHTML = obj.RGB_R;\n"+
      "                    document.getElementById(\"idRGB_Gvalue\").innerHTML = obj.RGB_G;\n"+
      "                    document.getElementById(\"idRGB_Bvalue\").innerHTML = obj.RGB_B;\n"+
      "                    document.getElementById(\"idenginevalue\").innerHTML = obj.engine;\n"+
      "                    document.getElementById(\"Ledvalue\").innerHTML = obj.LedState_value;\n"+
      " document.getElementById(\"idRGB_R\").value = obj.RGB_R;\n"+
      " document.getElementById(\"idRGB_G\").value = obj.RGB_G;\n"+
      " document.getElementById(\"idRGB_B\").value = obj.RGB_B;\n"+
      " document.getElementById(\"idengine\").value = obj.engine;\n"+
       " document.getElementById(\"range\").value = obj.LedState_value;\n"+
      "                  //  document.getElementById(\"info\").innerHTML += obj.light + obj.Humidity + obj.Temperature+\"<br>\";\n"+
      "                };\n"+
      "                ws.onerror = function () { // 发生错误时触发\n"+
      "                    document.getElementById(\"info\").innerHTML += \"通讯发送错误!\" + \"<br>\";\n"+
      "                };\n"+
      "                ws.onclose = function () { // 连接关闭时触发\n"+
      "                    document.getElementById(\"info\").innerHTML += \"WebSocketTest连接已关闭!\" + \"<br>\";\n"+
      "                };\n"+
      "            }\n"+
      "            else {\n"+
      "                document.getElementById(\"info\").innerHTML = \"浏览器不支持 WebSocket!\";\n"+
      "            }\n"+
      "        };\n"+
      "        function ledoff() {\n"+
      "            txtJson.ledstate = \"led_off\";\n"+
      "            console.log(txtJson);\n"+
      "           // document.getElementById(\"LedState\").innerHTML = \"关闭\";\n"+
      "            ws.send(JSON.stringify(txtJson)); // 向服务器发送数据\n"+
      "        }\n"+
      "        function ledon() {\n"+
      "            txtJson.ledstate = \"led_on\";\n"+
      "            console.log(txtJson);\n"+
      "          //  document.getElementById(\"LedState\").innerHTML = \"打开\";\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "        }\n"+
      "        function LedStatef() {\n"+
      "            var LedState_value = document.getElementById(\"range\").value;\n"+
      "            txtJson.LedState_value = LedState_value;\n"+
      "            document.getElementById(\"Ledvalue\").innerHTML = LedState_value;\n"+
      "            console.log(txtJson);\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "        }\n"+
      "        var ControlState_Flag = true ;\n"+
      "        function changeState(){\n"+
      "            if (ControlState_Flag) {\n"+
      "                txtJson.ControlState = \"Automatic\";\n"+
      "               // document.getElementById(\"ControlState\").innerHTML = \"自动\";\n"+
      "                ControlState_Flag = false;\n"+
      "            }\n"+
      "            else {\n"+
      "                txtJson.ControlState = \"Manual\";\n"+
      "               // document.getElementById(\"ControlState\").innerHTML = \"手动\";\n"+
      "                ControlState_Flag = true;\n"+
      "            }\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "            console.log(txtJson);\n"+
      "        }\n"+
      "        function fRGB_R() {\n"+
      "            var RGB_R_value = document.getElementById(\"idRGB_R\").value;\n"+
      "            txtJson.RGB_R = RGB_R_value;\n"+
      "            document.getElementById(\"idRGB_Rvalue\").innerHTML = RGB_R_value;\n"+
      "            console.log(txtJson);\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "        }\n"+
      "        function fRGB_G() {\n"+
      "            var RGB_G_value = document.getElementById(\"idRGB_G\").value;\n"+
      "            txtJson.RGB_G = RGB_G_value;\n"+
      "            document.getElementById(\"idRGB_Gvalue\").innerHTML = RGB_G_value;\n"+
      "            console.log(txtJson);\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "        }\n"+
      "        function fRGB_B() {\n"+
      "            var RGB_B_value = document.getElementById(\"idRGB_B\").value;\n"+
      "            txtJson.RGB_B = RGB_B_value;\n"+
      "            document.getElementById(\"idRGB_Bvalue\").innerHTML = RGB_B_value;\n"+
      "            console.log(txtJson);\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "        }\n"+
      "        function fengine() {\n"+
      "            var engine_value = document.getElementById(\"idengine\").value;\n"+
      "            txtJson.engine = engine_value;\n"+
      "            console.log(txtJson);\n"+
      "            ws.send(JSON.stringify(txtJson));\n"+
      "        }\n"+
      "    </script>\n"+
      "</head>\n"+
      "<body>\n"+
      "    <div id=\"container\" style=\"width: 1000px; height: 1000px;\">\n"+
      "        <div id=\"header\" style=\"background-color:#FFA500;\">\n"+
      "            <h1 style=\"margin-bottom: 0; text-align: center;\">智能温室光照补偿控制系统</h1>\n"+
      "        </div>\n"+
      "        <div id=\"menu\" style=\"background-color:#FFD700;height:500px;width:500px;float:left;\">\n"+
      "            <b>菜单</b>\n"+
      "            <p>\n"+
      "                打开光照:\n"+
      "                <button onclick=\"ledoff()\" id=\"but1\">关灯</button>\n"+
      "                <button onclick=\"ledon()\" id=\"but2\">开灯</button>\n"+
      "                当前状态:<font style=\"color:green\" size=\"3\" id=\"LedState\">关闭</font>\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                设置光照强度:\n"+
      "                <input type=\"range\" id=\"range\" min=\"0\" max=\"100\" value=\"0\" oninput=\"LedStatef()\" />\n"+
      "                亮度:<font style=\"color:green\" size=\"3\" id=\"Ledvalue\">0</font>%\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                设置RGB_R:\n"+
      "                <input type=\"range\" id=\"idRGB_R\" min=\"0\" max=\"255\" value=\"0\" oninput=\"fRGB_R()\" />\n"+
      "                RGB_R:<font style=\"color:green\" size=\"3\" id=\"idRGB_Rvalue\">0</font>\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                设置RGB_G:\n"+
      "                <input type=\"range\" id=\"idRGB_G\" min=\"0\" max=\"255\" value=\"150\" oninput=\"fRGB_G()\" />\n"+
      "                RGB_G:<font style=\"color:green\" size=\"3\" id=\"idRGB_Gvalue\">150</font>\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                设置RGB_B:\n"+
      "                <input type=\"range\" id=\"idRGB_B\" min=\"0\" max=\"255\" value=\"0\" oninput=\"fRGB_B()\" />\n"+
      "                RGB_B:<font style=\"color:green\" size=\"3\" id=\"idRGB_Bvalue\">0</font>\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                设置舵机角度:\n"+
      "                <input type=\"range\" id=\"idengine\" min=\"0\" max=\"180\" value=\"0\" oninput=\"fengine()\" />\n"+
      "                角度:<font style=\"color:green\" size=\"3\" id=\"idenginevalue\">0</font>度\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                当前温室温度:<font style=\"color:green\" size=\"3\" id=\"TemperatureIntensity\">00</font>℃\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                当前温室湿度:<font style=\"color:green\" size=\"3\" id=\"HumidityIntensity\">00</font>RH\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                当前光照强度:<font style=\"color:green\" size=\"3\" id=\"LightIntensity\">00</font>\n"+
      "            </p>\n"+
      "            <p>\n"+
      "\n"+
      "\n"+
      "            </p>\n"+
      "            <p>\n"+
      "                <button onclick=\"changeState()\" id=\"but4\">切换模式</button>\n"+
      "                当前模式:<font style=\"color:green\" size=\"3\" id=\"ControlState\">自动</font>\n"+
      "\n"+
      "            </p>\n"+
      "        </div>\n"+
      "        <div id=\"content\" style=\"background-color:#EEEEEE;height:500px;width:200px;float:right;\">\n"+
      "            <div id=\"info\" >调试内容 <br> </div>\n"+
      "        </div>\n"+
      "        <div id=\"footer\" style=\"background-color: #FFA500; clear: both; text-align: center;\">\n"+
      "            版权 © lalala.com\n"+
      "        </div>\n"+
      "    </div>\n"+
      "</body>\n"+
      "</html>\n"

        ;



void data_pick()//采集外设数据，并打包成json发送到客户端
{
	cJSON *TCP = cJSON_CreateObject();				//创建一个对象
	
	cJSON_AddNumberToObject(TCP,"light",analogRead(ligth_pin));	//构造json数据
	cJSON_AddNumberToObject(TCP,"Humidity",Humidity);	    	//添加整型数字 
	cJSON_AddNumberToObject(TCP,"Temperature",Temperature);	
  cJSON_AddStringToObject(TCP,"ControlState",mdata.ControlState);
  cJSON_AddStringToObject(TCP,"ledstate",mdata.ledstate);
  cJSON_AddNumberToObject(TCP,"LedState_value",mdata.LedState_value);

  cJSON_AddNumberToObject(TCP,"RGB_R",mdata.RGB_R);
  cJSON_AddNumberToObject(TCP,"RGB_G",mdata.RGB_G);
  cJSON_AddNumberToObject(TCP,"RGB_B",mdata.RGB_B);
  cJSON_AddNumberToObject(TCP,"engine",mdata.engine);

	json_data = cJSON_Print(TCP);				//JSON数据结构转换为JSON字符串

}

void notFound(AsyncWebServerRequest *request) {       //客户端错误请求时调用
    request->send(404, "text/plain", "Not found");
}

AsyncWebSocket ws("/"); // WebSocket对象，url为/
void data_deal(char* resivedata)//数据处理函数，对客户端发来的数据进行解析，如果执行比较大的程序，比如刷新led建议标记，在主循环处理。
{
  // Serial.printf("这里是数据处理函数%s\n", resivedata);
   if(strcmp(resivedata,"led_off")==0){ //如果是普通指令则在此进行判断，json数据在else中判断。
     led_on;
   }
   else if(strcmp(resivedata,"led_on")==0){//这两行已经不再适用，就是懒得删
     led_off;
   }
   else{
   
    cJSON * root = NULL;
    root = cJSON_Parse(resivedata); 
    if(root == NULL){
         Serial.printf("json pack into cjson error...");
    }
    else{
    char* ledstate = cJSON_GetObjectItem(root,"ledstate")->valuestring;
    char* LedState_value = cJSON_GetObjectItem(root,"LedState_value")->valuestring;
    char* ControlState = cJSON_GetObjectItem(root,"ControlState")->valuestring;
    char* RGB_R = cJSON_GetObjectItem(root,"RGB_R")->valuestring;
    char* RGB_G = cJSON_GetObjectItem(root,"RGB_G")->valuestring;
    char* RGB_B = cJSON_GetObjectItem(root,"RGB_B")->valuestring;
    char* engine = cJSON_GetObjectItem(root,"engine")->valuestring;

    //Serial.printf("ledstate:%s，LedState_value:%s，ControlState:%s，\n",ledstate,LedState_value,ControlState);
    //Serial.printf("%d\n",(uint8_t)(atoi(LedState_value)*2.55));

    mdata.LedState_value=(uint8_t)(atoi(LedState_value)); //将数据传回mdata结构体
    mdata.RGB_R=(uint8_t)atoi(RGB_R);
    mdata.RGB_G=(uint8_t)atoi(RGB_G);
    mdata.RGB_B=(uint8_t)atoi(RGB_B);
    mdata.engine=(uint8_t)atoi(engine);
    strcpy(mdata.ledstate,ledstate);
    strcpy(mdata.ControlState,ControlState);
    
    if(strcmp(mdata.ledstate,"led_off")==0){ //led开关
      led_on;
    }
    else if(strcmp(mdata.ledstate,"led_on")==0){
      led_off;
    }
   


    cJSON_Delete(root);//释放内存
   
    }

   }

}
// WebSocket事件回调函数
uint32_t clientID=0;   //用于存储连接对象的id
void onEventHandle(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
{
  if (type == WS_EVT_CONNECT) // 有客户端建立连接
  {
    Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
    clientID= client->id();
    client->printf("Hello Client %u !", client->id()); // 向客户端发送数据
    client->ping();                                    // 向客户端发送ping
  }
  else if (type == WS_EVT_DISCONNECT) // 有客户端断开连接
  {
    //Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
    connet_flag=0;
    Serial.printf("服务端断开连接\n");
  }
  else if (type == WS_EVT_ERROR) // 发生错误
  {
    Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t *)arg), (char *)data);
  }
  else if (type == WS_EVT_PONG) // 收到客户端对服务器发出的ping进行应答（pong消息）
  {
    Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char *)data : "");
  }
  else if (type == WS_EVT_DATA) // 收到来自客户端的数据
  {
    AwsFrameInfo *info = (AwsFrameInfo *)arg;
    Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len);
    data[len] = 0;
    data_deal((char *)data);
    //Serial.printf("%s\n", (char *)data);
  }
}
void tim1Interrupt()
{
   if(connet_flag)//如果连接打开
    {
      data_pick();
     // Serial.printf("%s\n", json_data);
      ws.printf(clientID, json_data);//向建立连接的客户端发送信息
      ws.cleanupClients();     // 关闭过多的WebSocket连接以节省资源
     
    } 
    else{
      // Serial.printf("等待连接建立...\n"); 
    }
}

static TimerHandle_t timer0_Handle=NULL;
static TimerHandle_t timer2_Handle=NULL;

void timer_callback();
void timer2_callback();
void setup() {
    Serial.begin(115200);

    pinMode(led_pin,OUTPUT); //初始化led引脚，并关闭led
    digitalWrite(led_pin,HIGH);

    DHT11.setup(T_S_pin); //初始化温湿度传感器


    pixels.begin();       //RGB初始化
    pixels.clear();
    pixels.setPixelColor(0, pixels.Color(0, 150, 0));
    pixels.setBrightness(0);
    pixels.show();

    tft.init(240, 240); //tft初始化
    tft.fillScreen(BLACK);
    tft.setTextWrap(false);

    tft.setCursor(40, 0);
    tft.setTextColor(GREEN);
    tft.setTextSize(2);
    tft.println("ControlSystem");
    tft.setTextColor(WHITE);

    WiFi.mode(WIFI_STA);     //wifi 的打开和连接
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.printf("WiFi Failed!\n");//串口输出信息
        tft.println("WiFi Failed!");//显示屏输出信息
        return;
    }
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());   //获取到的ip地址，这个地址之后要显示在屏幕上

      ws.onEvent(onEventHandle); // WebSocket事件回调函数
      server.addHandler(&ws);    // 将WebSocket添加到服务器中

      server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){   //url 主页面请求
          request->send(200, "text/html",web_main);
      });

      server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ //账户密码提交页面请求
          String message;
          char resive_name[10]={0},   //存放客户端发来的账号
                resive_pswd[10]={0};   //存放客户端发来的密码
          if (request->hasParam("usernum", true)) {  //找usernum这个键
              strcpy(resive_name,request->getParam("usernum", true)->value().c_str());
              Serial.printf("usernum: %s\n",resive_name);
          }
          if (request->hasParam("pswd", true)){//找pswd这个键
            // message = request->getParam("pswd", true)->value();
              strcpy(resive_pswd,request->getParam("pswd", true)->value().c_str());
              Serial.printf("pswd: %s\n",resive_pswd);
          }
          if(strcmp(resive_name,hujingxuan.u_nume)==0){ //得到提交数据之后开始密码校验
            Serial.printf("已找到用户:%s,开始密码校验...\n",resive_name);
            if(strcmp(resive_pswd,hujingxuan.u_pawd)==0){
            Serial.printf("用户密码正确!\n");
            connet_flag=1;
            request->send(200, "text/html",web_app);
            }
            else{
            Serial.printf("对不起，您输入的密码有误!\n");
            }
          }
          else{
            request->send(200, "text/html",web_main);
            Serial.printf("找不到指定用户，请重新输入!\n");
          }
      });
      server.onNotFound(notFound);
      server.begin();
    
  //开启一个freertos定时器，注意，定时器1不能时间间隔太短否则会导致消息堆积，发不出去
  timer0_Handle=xTimerCreate("timer0_Handle",250,pdTRUE,(void*)1,(TimerCallbackFunction_t )timer_callback);
  if(timer0_Handle!=NULL){xTimerStart(timer0_Handle,0);}

  timer2_Handle=xTimerCreate("timer2_Handle",1000,pdTRUE,(void*)2,(TimerCallbackFunction_t )timer2_callback);
  if(timer2_Handle!=NULL){xTimerStart(timer2_Handle,0);} 


  Serial.printf("初始化结束\n");
  tft.print("IP:");
  tft.println(WiFi.localIP());
}
unsigned char time1_flag=0,time2_flag=0;
ControlData dataLast={"0",1,0,0,0,"0",0};//用于存储上一次的数据，仅当数据改变时才刷新屏幕
static char key_flag=1;//用于按键翻转
void loop() {
   
  if(digitalRead(key_pin)==0)
  {
    while(!digitalRead(key_pin));//注:消抖，但不建议这样写，因为会阻塞程序
    Serial.printf("key_flag: %d\n",key_flag);
    if(key_flag){

      analogRead(ligth_pin);
      key_flag=0;
      strcpy(mdata.ControlState,"Automatic");
    }
    else{
      key_flag=1;
       strcpy(mdata.ControlState,"Manual");
    }
    
  }
   if(time1_flag)
   {
     time1_flag=0;
     tim1Interrupt(); //定时回调，向网页推送消息


    if(!strcmp(mdata.ControlState,"Automatic"))//把自动控制的代码放在200ms的回调之中，防止太快
    {
      Serial.printf("自动模式\n");
      uint16_t analog=analogRead(ligth_pin);
      if(analog<120)analog=120;  //阈值120一下视为最黑，必须要做这个处理，否则在之后的表达式会带入负数，引发错误
      if(analog>1800)analog=1800;

      uint8_t Led_value=0.059523*(analog-120);//这里将120视为最大光强

      mdata.LedState_value=Led_value;//数据传回结构体，触发显示屏刷新
      //Serial.printf("%d,%d\n",analog,Led_value);
      pixels.setPixelColor(0, pixels.Color(mdata.RGB_R,mdata.RGB_G,mdata.RGB_B));//改变颜色和亮度
      pixels.setBrightness((uint8_t)(Led_value*2.55));
      pixels.show();

    }
    else{//手动模式
      //Serial.printf("手动模式\n");
    pixels.setPixelColor(0, pixels.Color(mdata.RGB_R,mdata.RGB_G,mdata.RGB_B));//改变颜色和亮度
    pixels.setBrightness(mdata.LedState_value*2.55);
    pixels.show();

    }
   }

   if(time2_flag)
   {
      time2_flag=0;
      if(((int)DHT11.getHumidity()<500)&&((int)DHT11.getTemperature()<500))//滤除错误数据
      {
        Humidity=(int)DHT11.getHumidity();
        Temperature=(int)DHT11.getTemperature();
       // Serial.printf("Humidity=%d,Temperature=%d\n",(int)DHT11.getHumidity(),(int)DHT11.getTemperature());
      }
   }
  if((strcmp(dataLast.ControlState,mdata.ControlState))||  //这里只放刷新屏幕的东西，具体实现不在这
     (strcmp(dataLast.ledstate,mdata.ledstate))||
     (dataLast.LedState_value!=mdata.LedState_value)||
     (dataLast.RGB_B!=mdata.RGB_B)||
     (dataLast.RGB_G!=mdata.RGB_G)||
     (dataLast.RGB_R!=mdata.RGB_R)||
     (dataLast.engine!=mdata.engine)
     )
  {
    tft.drawLine(10, 40, 230,40 , WHITE);
    tft.drawLine(10, 210, 230,210 , WHITE);

    tft.setCursor(80, 215);
    tft.setTextColor(GREEN,BLACK);
    tft.setTextSize(2);
    tft.printf("@balabal");
//-----------------正式内容-----------------------------
    tft.setCursor(0, 50);  //led开关状态
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.printf("state :");
    tft.setTextColor(GREEN,BLACK);
    tft.printf(mdata.ledstate);  
    tft.println("    "); 
    
    tft.setTextColor(WHITE);//led亮度
    tft.printf("brightness :");
    tft.setTextColor(GREEN,BLACK);
    tft.printf("%d",mdata.LedState_value);  
    tft.println("    "); 
    

    tft.setTextColor(WHITE);
    tft.printf("RGB_R:");
    tft.setTextColor(GREEN,BLACK);
    tft.printf("%d",mdata.RGB_R);  
    tft.println("    "); 

    tft.setTextColor(WHITE);
    tft.printf("RGB_G:");
    tft.setTextColor(GREEN,BLACK);
    tft.printf("%d",mdata.RGB_G);  
    tft.println("    "); 

    tft.setTextColor(WHITE);
    tft.printf("RGB_B:");
    tft.setTextColor(GREEN,BLACK);
    tft.printf("%d",mdata.RGB_B);  
    tft.println("    "); 

    tft.setTextColor(WHITE);//控制方式
    tft.printf("concrol :");
    tft.setTextColor(GREEN,BLACK);
    tft.printf(mdata.ControlState);  
    tft.println("    "); 

    tft.setTextColor(WHITE);//舵机角度
    tft.printf("EngineAngle :");
    tft.setTextColor(GREEN,BLACK);
    tft.printf("%d",mdata.engine);  
    tft.println("    "); 

   

    dataLast.RGB_B=mdata.RGB_B;//传递数据为上次
    dataLast.RGB_G=mdata.RGB_G;
    dataLast.RGB_R=mdata.RGB_R;
    dataLast.engine=mdata.engine;
    dataLast.LedState_value=mdata.LedState_value; 
    strcpy(dataLast.ledstate,mdata.ledstate);
    strcpy(dataLast.ControlState,mdata.ControlState);
  
  }
}
void timer_callback()//注意，这个函数还是在内部任务调用的，所以不能放太多内容，否则会堆栈溢出
{
  time1_flag=1;
}
void timer2_callback()
{
  time2_flag=1;
}
